﻿/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#include "DiaglogComSetting.h"
#include <QSettings>
#include "BurnToolCommon/StdAfx.h"
#include "BurnDlg/BurnDlg.h"
#include "DataConvertor.h"

namespace {
    const int DEFAULT_BAUD = 115200;
    const int DEFAULT_DATABITS = 8;
    const int DEFAULT_EACHPACKAGESIZE = 1024;
    const int DEFAULT_FORCEREADTIME = 10;
    const int DEFAULT_TOTALNUM = 20;
    const int DEFAULT_NUMPERLINE = 10;
    const int CHIP4GCAT1_MAX_TOTAL = 16;
    const int CHIP4GCAT1_MAX_LINE = 8;
    const int CHIP4GCAT1_MIN_LINE = 4;
}

DiaglogComSetting::DiaglogComSetting(QWidget *pParent)
    : QWidget(pParent),
      ui(new Ui::MenuSettings()),
      baud(DEFAULT_BAUD),
      parity(QSerialPort::NoParity),
      databits(DEFAULT_DATABITS),
      stopbits(1),
      flowctrl(0),
      eachPackageSize(DEFAULT_EACHPACKAGESIZE),
      isForceRead(true),
      forceReadTime(DEFAULT_FORCEREADTIME),
      independent(false),
      isReopenComFlah(false),
      isResetAfterSuccess(false),
      isSwitchAfterLoader(false),
      totalNum(DEFAULT_TOTALNUM),
      numPerLine(DEFAULT_NUMPERLINE)
{
    InitUi();
}

DiaglogComSetting::~DiaglogComSetting()
{
    if (ui != nullptr) {
        delete ui;
        ui = nullptr;
    }
}

void DiaglogComSetting::InitUi()
{
    ui->setupUi(this);
    setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
    setWindowTitle(QObject::tr("Settings"));
    QString path = Global::GetAppConfigPath();
    path += "\\config_" + Global::ChipTypeIdToString(Global::currentChipTypeId);
    QSettings cfg(path  + "\\SettingConfigValue.ini", QSettings::IniFormat);
    QStringList baudList = cfg.value("SettingConfigValue/BAUND_RATE").toStringList();\
    if (baudList.empty()) {
        baudList = DataConvertor::GetValidBaud();
    }
    ui->comboBoxBaud->addItems(baudList);
    QStringList databitList = cfg.value("SettingConfigValue/DATA_BIT").toStringList();
    if (databitList.empty()) {
        databitList = DataConvertor::GetValidDatabit();
    }
    ui->comboBoxDataBit->addItems(databitList);
    QStringList stopbitList = cfg.value("SettingConfigValue/STOP_BIT").toStringList();
    if (stopbitList.empty()) {
        stopbitList = DataConvertor::GetValidStopbit();
    }
    ui->comboBoxStopBit->addItems(stopbitList);
    QStringList parityList = cfg.value("SettingConfigValue/PARITY").toStringList();
    if (parityList.empty()) {
        parityList = DataConvertor::GetValidParity();
    }
    ui->comboBoxParity->addItems(parityList);
    QStringList flowCtrlList = cfg.value("SettingConfigValue/FLOW_CTRL").toStringList();
    if (flowCtrlList.empty()) {
        flowCtrlList = DataConvertor::GetValidFlowctrl();
    }
    ui->comboBoxFlowCtrl->addItems(flowCtrlList);
    QStringList packageSize = cfg.value("SettingConfigValue/PACKAGE_SIZE").toStringList();
    if (packageSize.empty()) {
        packageSize = DataConvertor::GetValidPackageSize();
    }
    ui->comboBoxPackageSize->addItems(packageSize);
    QVariant switchBaudRate = cfg.value("SettingConfigValue/SWITCH_BAUD_RATE");
    if (switchBaudRate.isValid()) {
        ui->cbSwitchAfterLoader->setEnabled(switchBaudRate.toInt() == 0 ? false : true);
    }
    SetCurrentValue();
    QRegExp rx0("^[1-9]{1}$|^1[0-9]$|^2[0]$");
    QRegExpValidator *pReg0 = new QRegExpValidator(rx0, this);
    if (pReg0 != nullptr) {
        ui->lineEditTotleNum->setValidator(pReg0);
        delete pReg0;
    }
    QRegExp rx1("^[1-9]{1}$|^1[0]$");
    QRegExpValidator *pReg1 = new QRegExpValidator(rx1, this);
    if (pReg1 != nullptr) {
        ui->lineEditNumPerLine->setValidator(pReg1);
        delete pReg1;
    }
    connect(ui->buttonOK, &QPushButton::clicked, this, &DiaglogComSetting::SlotOkButtonClick);
    connect(ui->buttonCancel, &QPushButton::clicked, this, &DiaglogComSetting::SlotCancelButtonClick);
}

void DiaglogComSetting::SlotOkButtonClick()
{
    baud = ui->comboBoxBaud->currentText().toInt();
    databits = ui->comboBoxDataBit->currentText().toInt();
    stopbits = ui->comboBoxStopBit->currentText().toInt();
    QString strParity = ui->comboBoxParity->currentText();
    parity = DataConvertor::ParityQString2Char(strParity);
    QString strFlowctrl = ui->comboBoxFlowCtrl->currentText();
    flowctrl = DataConvertor::FlowctrlQString2Int(strFlowctrl);
    eachPackageSize = ui->comboBoxPackageSize->currentText().toInt();
    isForceRead = ui->checkBoxReadTime->isChecked();
    forceReadTime = DataConvertor::Str2U32DecHex(ui->lineEditReadTime->text());
    totalNum = DataConvertor::Str2U32DecHex(ui->lineEditTotleNum->text());
    numPerLine = DataConvertor::Str2U32DecHex(ui->lineEditNumPerLine->text());
    independent = ui->checkBoxIndependent->isChecked();
    isReopenComFlah = ui->checkBoxComEverytime->isChecked();
    isResetAfterSuccess = ui->checkBoxResetAfterSuccess->isChecked();
    isSwitchAfterLoader = ui->cbSwitchAfterLoader->isChecked();
    emit SignalSettingSuccess();
    this->close();
}

void DiaglogComSetting::SlotCancelButtonClick()
{
    SetCurrentValue();
    this->close();
}

void DiaglogComSetting::SetCurrentValue() const
{
    ui->comboBoxBaud->setCurrentText(QString::number(baud));
    ui->comboBoxDataBit->setCurrentText(QString::number(databits));
    ui->comboBoxStopBit->setCurrentText(QString::number(stopbits));
    ui->comboBoxParity->setCurrentText(DataConvertor::ParityChar2QString(parity));
    ui->comboBoxFlowCtrl->setCurrentText(DataConvertor::FlowctrlInt2QString(flowctrl));
    ui->comboBoxPackageSize->setCurrentText(QString::number(eachPackageSize));
    if (!isForceRead) {
        ui->checkBoxReadTime->setCheckState(Qt::Unchecked);
    } else {
        ui->checkBoxReadTime->setCheckState(Qt::Checked);
    }
    ui->checkBoxReadTime->setEnabled(false);
    ui->lineEditReadTime->setText(QString::number(forceReadTime));
    ui->lineEditReadTime->setEnabled(false);
    if (!independent) {
        ui->checkBoxIndependent->setCheckState(Qt::Unchecked);
    } else {
        ui->checkBoxIndependent->setCheckState(Qt::Checked);
    }

    if (!isReopenComFlah) {
        ui->checkBoxComEverytime->setCheckState(Qt::Unchecked);
    } else {
        ui->checkBoxComEverytime->setCheckState(Qt::Checked);
    }

    if (!isResetAfterSuccess) {
        ui->checkBoxResetAfterSuccess->setCheckState(Qt::Unchecked);
    } else {
        ui->checkBoxResetAfterSuccess->setCheckState(Qt::Checked);
    }

    if (!isSwitchAfterLoader) {
        ui->cbSwitchAfterLoader->setCheckState(Qt::Unchecked);
    } else {
        ui->cbSwitchAfterLoader->setCheckState(Qt::Checked);
    }
    ui->lineEditTotleNum->setText(QString::number(totalNum));
    ui->lineEditNumPerLine->setText(QString::number(numPerLine));
}

void DiaglogComSetting::GetComConfig(int &baudRate, int &databit, int &stopbit,
                                     QSerialPort::Parity &tparity, int &flowControl) const
{
    baudRate = this->baud;
    databit = this->databits;
    stopbit = this->stopbits;
    tparity = this->parity;
    flowControl = this->flowctrl;
}

void DiaglogComSetting::SetComConfig(const int &baudRate, const int &databit,
    const int &stopbit, const QSerialPort::Parity &tparity, const int &flowControl)
{
    this->baud = baudRate;
    this->parity = tparity;
    this->databits = databit;
    this->stopbits = stopbit;
    this->flowctrl = flowControl;
}

void DiaglogComSetting::SetForceRead(bool forceRead)
{
    this->isForceRead = forceRead;
}

bool DiaglogComSetting::GetForceRead() const
{
    return isForceRead;
}

void DiaglogComSetting::SetForceReadTimr(UINT time)
{
    this->forceReadTime = time;
}

UINT DiaglogComSetting::GetForceReadTime() const
{
    return forceReadTime;
}

void DiaglogComSetting::SetMultipleBurnParam(unsigned int totalNumber, unsigned int numPerLines,
    bool indenpendent, bool reopenComFlag)
{
    this->totalNum = totalNumber;
    this->numPerLine = numPerLines;
    this->independent = indenpendent;
    this->isReopenComFlah = reopenComFlag;
}

void DiaglogComSetting::SetIsResetAfterSuccess(bool resetAfterSuccess)
{
    this->isResetAfterSuccess = resetAfterSuccess;
}

void DiaglogComSetting::SetIsSwitchAfterLoader(bool switchAfterLoader)
{
    this->isSwitchAfterLoader = switchAfterLoader;
}

void DiaglogComSetting::GetMultipleBurnParam(unsigned int &totalNumber, unsigned int &numPerLines,
    bool &indenpendent, bool &reopenComFlag) const
{
    totalNumber = this->totalNum;
    numPerLines = this->numPerLine;
    indenpendent = this->independent;
    reopenComFlag = this->isReopenComFlah;
}

void DiaglogComSetting::GetIsResetAfterSuccess(bool &resetAfterSuccess) const
{
    resetAfterSuccess = this->isResetAfterSuccess;
}

void DiaglogComSetting::GetIsSwitchAfterLoader(bool &isSwitchAfterLoaderBurn) const
{
    isSwitchAfterLoaderBurn = this->isSwitchAfterLoader;
}

void DiaglogComSetting::mousePressEvent(QMouseEvent *event)
{
    if (event->button() != Qt::LeftButton) {
        return;
    }
    if (DataConvertor::Str2U32DecHex(ui->lineEditNumPerLine->text()) >
        DataConvertor::Str2U32DecHex(ui->lineEditTotleNum->text())) {
        ui->lineEditNumPerLine->setText(ui->lineEditTotleNum->text());
    }
}

void DiaglogComSetting::Set4GCat1TotalAndLineNum(ChipType chipType)
{
    if (chipType != ChipType::USB4GCAT1 && chipType != ChipType::WIFI4GCAT1 && chipType != ChipType::USBHI3322) {
        return;
    }

    ui->lineEditTotleNum->setValidator(new QRegExpValidator(QRegExp("^[1-9]{1}$|^1[0-6]$"), this));
    ui->lineEditNumPerLine->setValidator(new QRegExpValidator(QRegExp("^[4-8]{1}$"), this));
    if (totalNum > CHIP4GCAT1_MAX_TOTAL) {
        totalNum = CHIP4GCAT1_MAX_TOTAL;
    }
    if (numPerLine > CHIP4GCAT1_MAX_LINE) {
        numPerLine = CHIP4GCAT1_MAX_LINE;
    } else if (numPerLine < CHIP4GCAT1_MIN_LINE) {
        numPerLine = CHIP4GCAT1_MIN_LINE;
    }
}

int DiaglogComSetting::GetYModemPackageSize() const
{
    return eachPackageSize;
}

void DiaglogComSetting::SetYModemPackageSize(int packageSize)
{
    this->eachPackageSize = packageSize;
}

void DiaglogComSetting::Set3XSettingShow(ChipType chipType)
{
    ui->comboBoxPackageSize->clear();
    if (chipType == ChipType::SPARTA) {
        ui->comboBoxPackageSize->addItems(DataConvertor::GetValidPackageSize3X());
    } else {
        ui->comboBoxPackageSize->addItem("4096");
    }
    ui->comboBoxPackageSize->setCurrentText(QString::number(eachPackageSize));
    if (!isResetAfterSuccess) {
        ui->checkBoxResetAfterSuccess->setCheckState(Qt::Unchecked);
    } else {
        ui->checkBoxResetAfterSuccess->setCheckState(Qt::Checked);
    }
    ui->cbSwitchAfterLoader->hide();
    ui->lineEditReadTime->hide();
    ui->checkBoxReadTime->hide();
    ui->checkBoxComEverytime->hide();
    this->independent = true;
    ui->checkBoxIndependent->setCheckState(Qt::Checked);
    ui->checkBoxIndependent->hide();
    ui->gridLayout_2->update();
    QRegExp rx("^[1-9]{1}$|^[12][0-9]$|^3[012]$");
    QRegExpValidator *pReg = new QRegExpValidator(rx, this);
    if (pReg != nullptr) {
        ui->lineEditTotleNum->setValidator(pReg);
        delete pReg;
    }
    QRegExp rx1("^[4-8]{1}$");
    QRegExpValidator *pReg1 = new QRegExpValidator(rx1, this);
    if (pReg1 != nullptr) {
        ui->lineEditNumPerLine->setValidator(pReg1);
        delete pReg1;
    }
}

void DiaglogComSetting::ComSettingEnable(bool isEnable) const
{
    ui->comboBoxBaud->setEnabled(isEnable);
    ui->comboBoxDataBit->setEnabled(isEnable);
    ui->comboBoxStopBit->setEnabled(isEnable);
    ui->comboBoxParity->setEnabled(isEnable);
    ui->comboBoxFlowCtrl->setEnabled(isEnable);
}
